"""
使用示例:
jsonl = JsonLReader("fails_libs.jsonl")
datas = jsonl.find_all("name like '%Library' and state_chinese like '俄%'")
with JsonLWriter("test_jsonl.jsonl", mode='a') as jsonl:
    jsonl.add(datas[3])
    jsonl.add(datas[4])
    jsonl.add(datas[5])
pass
"""

import json
import re
from typing import Any, Dict, List
from decimal import Decimal


class DecimalEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Decimal):
            return str(obj)  # 转换为字符串
            # return float(obj)  # 或转换为浮点数
        return super().default(obj)

class WhereConditionEvaluator:
    """解析并评估MySQL风格的WHERE条件表达式（严格单引号字符串类型判断）"""
    
    def __init__(self):
        # 扩展正则：支持两种模式
        # 模式1：字段 + 普通运算符（=、!=、>等） + 值（单引号字符串/数字/布尔）
        # 模式2：字段 + is (not)? null
        self.condition_pattern = re.compile(
            r"(?P<field>\w+)\s*(?:(?P<operator>=|!=|>|<|>=|<=|like)\s*(?P<value>'[^']*'|\w+)|(?P<is_null>is\s+(?:not\s+)?null))",
            re.IGNORECASE,
        )
        # 逻辑运算符分割正则
        self.logic_split_pattern = re.compile(r"\s+(and|or)\s+", re.IGNORECASE)
    
    def _parse_value(self, value_str: str) -> Any:
        """严格解析值类型：单引号包裹=字符串，否则尝试数字/布尔"""
        if value_str is None:
            return None
        
        value_str = value_str.strip()

        # 单引号包裹的内容 → 纯字符串类型
        if value_str.startswith("'") and value_str.endswith("'"):
            return value_str[1:-1]  # 去掉单引号，返回字符串

        # 无单引号：尝试解析为布尔/数字类型
        # 处理布尔值
        lower_val = value_str.lower()
        if lower_val == "true":
            return True
        elif lower_val == "false":
            return False

        # 处理数字（整数/浮点数）
        try:
            return int(value_str)
        except ValueError:
            try:
                return float(value_str)
            except ValueError:
                # 无单引号且非布尔/数字 → 视为无效或普通字符串（根据需求调整）
                return value_str

    def _evaluate_single_condition(
        self, field: str, operator: str, value: Any, is_null_type: str, data: Dict
    ) -> bool:
        """评估单个条件表达式（严格类型比较）"""
        # 获取字典中的字段值（不存在返回None）
        field_value = data.get(field)

        # 处理is null/is not null逻辑
        if is_null_type:
            is_null_type = is_null_type.strip().lower()
            if is_null_type == "is null":
                return field_value is None
            elif is_null_type == "is not null":
                return field_value is not None
        
        # 处理字段不存在或值为None的情况（普通运算符）
        if field_value is None:
            return False

        # 统一运算符为小写
        operator = operator.lower()

        # 严格按类型比较
        try:
            if operator == "=":
                return field_value == value
            elif operator == "!=":
                return field_value != value
            elif operator == ">":
                # 仅数字类型支持大小比较
                if isinstance(field_value, (int, float)) and isinstance(value, (int, float)):
                    return field_value > value
                else:
                    return False  # 非数字类型不支持>比较
            elif operator == "<":
                if isinstance(field_value, (int, float)) and isinstance(value, (int, float)):
                    return field_value < value
                else:
                    return False
            elif operator == ">=":
                if isinstance(field_value, (int, float)) and isinstance(value, (int, float)):
                    return field_value >= value
                else:
                    return False
            elif operator == "<=":
                if isinstance(field_value, (int, float)) and isinstance(value, (int, float)):
                    return field_value <= value
                else:
                    return False
            elif operator == "like":
                # like仅针对字符串类型
                if isinstance(field_value, str) and isinstance(value, str):
                    pattern = value.replace("%", ".*")
                    return bool(re.match(f"^{pattern}$", field_value, re.IGNORECASE))
                else:
                    return False
            else:
                return False
        except (TypeError, ValueError):
            return False

    def evaluate(self, condition_str: str, data: Dict[str, Any]) -> bool:
        """
        评估整个WHERE条件（严格单引号字符串类型判断）

        Args:
            condition_str: MySQL风格的WHERE条件字符串（单引号标识字符串）
            data: 要检查的字典数据

        Returns:
            bool: 是否满足条件
        """
        # 去除首尾空格
        condition_str = condition_str.strip()

        # 分割逻辑条件和运算符
        parts = self.logic_split_pattern.split(condition_str)
        if len(parts) % 2 == 0:
            raise ValueError("无效的条件表达式")

        # 提取条件和逻辑运算符
        conditions = parts[::2]
        logic_ops = parts[1::2]

        # 评估第一个条件
        match = self.condition_pattern.match(conditions[0].strip())
        if not match:
            raise ValueError(f"无法解析条件: {conditions[0]}")

        field = match.group("field")
        operator = match.group("operator")
        value = self._parse_value(match.group("value"))
        is_null_type = match.group("is_null")
        
        result = self._evaluate_single_condition(field, operator, value, is_null_type, data)

        # 依次评估后续条件
        for i in range(len(logic_ops)):
            condition = conditions[i + 1].strip()
            logic_op = logic_ops[i].lower()

            match = self.condition_pattern.match(condition)
            if not match:
                raise ValueError(f"无法解析条件: {condition}")

            field = match.group("field")
            operator = match.group("operator")
            value = self._parse_value(match.group("value"))
            is_null_type = match.group("is_null")
            
            current_result = self._evaluate_single_condition(
                field, operator, value, is_null_type, data
            )

            # 逻辑运算
            if logic_op == "and":
                result = result and current_result
                if not result:
                    break
            elif logic_op == "or":
                result = result or current_result
                if result:
                    break

        return result
    
class JsonLReader:
    def __init__(self, file_path):
        self.lines = []
        self.load_file(file_path)

    def load_file(self, file_path):
        with open(file_path, encoding="utf-8") as f:
            for line in f:
                if line:
                    self.lines.append(json.loads(line))

    def find_one(self, where):
        evaluator = WhereConditionEvaluator()
        for line in self.lines:
            if evaluator.evaluate(where, line):
                return line

    def find_many(self, where, count: int) -> List[Dict]:
        evaluator = WhereConditionEvaluator()
        ret = []
        for line in self.lines:
            if evaluator.evaluate(where, line):
                ret.append(line)
            if len(ret) >= count:
                break
        return ret

    def find_all(self, where):
        if not where:
            return self.lines
        return self.find_many(where, len(self.lines))


class JsonLWriter:
    """
    额外的类型支持：
        Decimal类型
    """
    def __init__(self, file_path, encoding="utf-8", mode="w"):
        self.file_path = file_path
        self.file = open(self.file_path, encoding=encoding, mode=mode)

    def __enter__(self):
        return self

    def add(self, data: Dict):
        self.file.write(json.dumps(data, cls=DecimalEncoder, ensure_ascii=False))
        self.file.write("\n")
        self.file.flush()

    def __exit__(self, exc_type, exc_val, exc_tb):
        try:
            self.file.close()
        except:
            pass
        finally:
            if exc_val:
                raise exc_val


# if __name__ == "__main__":
#     jsonl = JsonLReader("fails_libs.jsonl")
#     datas = jsonl.find_all("name like '%Library' and state_chinese like '俄%'")
#     with JsonLWriter("test_jsonl.jsonl", mode="a") as jsonl:
#         jsonl.add(datas[3])
#         jsonl.add(datas[4])
#         jsonl.add(datas[5])
#     pass
